import 'dart:async';
import 'dart:convert';

import 'package:chatbot/manager/dio_manager.dart';
import 'package:chatbot/model/completion_model.dart';
import 'package:chatbot/page/provider_example.dart';
import 'package:chatbot/page/vip_page.dart';
import 'package:chatbot/sse/sse_event_model.dart';
import 'package:chatbot/utils/colors.dart';
import 'package:chatbot/utils/utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:speech_to_text/speech_to_text.dart';
import 'package:speech_to_text/speech_to_text_provider.dart';

class CreatorTextPage extends StatefulWidget {
  final Creator creator;
  final SpeechToText speech;

  final SpeechToTextProvider speechProvider;


  const CreatorTextPage({super.key, required this.creator, required this.speech, required this.speechProvider});

  @override
  State<StatefulWidget> createState() {
    return CreatorTextState(creator: creator);
  }
}

class CreatorTextState extends State<CreatorTextPage> {
  final Creator creator;
  final TextEditingController _textEditingController = TextEditingController();
  final ScrollController _controller = ScrollController();

  CreatorTextState({required this.creator});

  String? menuTitle;
  String? menuDefaultValue;

  String? menu2Title;
  String? menu2DefaultValue;

  String? menu3Title;
  String? menu3DefaultValue;

  List<String> menuOptions = [];
  List<String> menu2Options = [];
  List<String> menu3Options = [];
  var focusNode = FocusNode();
  bool isNeedTextField = true;
  String result = "";
  StreamController<SSEModel>? streamController;
  StreamTransformer<Uint8List, List<int>> unit8Transformer =
      StreamTransformer.fromHandlers(
    handleData: (data, sink) {
      sink.add(List<int>.from(data));
    },
  );
  bool isCreating = false;
  String prompt = "";

  @override
  void initState() {
    super.initState();
    if (creator.menu != "") {
      if (creator.menu.contains("-") && creator.menu.contains("|")) {
        List<String> arrays = creator.menu.split("-");
        menuTitle = arrays[0];
        List<String> options = arrays[1].split("|");
        menuDefaultValue = options[0]; //默认第一个
        // menuSelectValue = menuDefaultValue;
        for (String menu in options) {
          menuOptions.add(menu);
        }
      }
    }

    if (creator.menu2 != "") {
      if (creator.menu2.contains("-") && creator.menu2.contains("|")) {
        List<String> arrays = creator.menu2.split("-");
        menu2Title = arrays[0];
        List<String> options = arrays[1].split("|");
        menu2DefaultValue = options[0]; //默认第一个
        // menu2SelectValue = menu2DefaultValue;
        for (String menu in options) {
          menu2Options.add(menu);
        }
      }
    }

    if (creator.menu3 != "") {
      if (creator.menu3.contains("-") && creator.menu3.contains("|")) {
        List<String> arrays = creator.menu3.split("-");
        menu3Title = arrays[0];
        List<String> options = arrays[1].split("|");
        menu3DefaultValue = options[0]; //默认第一个
        // menu3SelectValue = menu3DefaultValue;
        for (String menu in options) {
          menu3Options.add(menu);
        }
      }
    }
    isNeedTextField = creator.prompt.contains("{0}");
    if (mounted) {
      setState(() {});
    }
  }


  @override
  void dispose() {
    super.dispose();
    if (isCreating) {
      stopCreator();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: ChatColors.commonDarkColor,
      appBar: AppBar(
        elevation: 0,
        backgroundColor: ChatColors.commonLightColor,
        leading: IconButton(
            onPressed: () {
              Navigator.pop(context);
            },
            icon: const Icon(
              Icons.arrow_back_ios,
              color: Colors.white,
              size: 20,
            )),
        title: Text(
          creator.title,
          style: const TextStyle(
              color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600),
        ),
      ),
      body: GestureDetector(
          onTap: () {
            focusNode.unfocus();
          },
          child: Stack(
            alignment: Alignment.topCenter,
            children: [
              SingleChildScrollView(
                controller: _controller,
                child: Column(
                  children: [
                    menuOptions.isNotEmpty
                        ? getDropMenu(
                            menuTitle!, menuDefaultValue!, menuOptions,
                            (value) {
                            setState(() {
                              menuDefaultValue = value;
                            });
                          })
                        : Container(),
                    menu2Options.isNotEmpty
                        ? getDropMenu(
                            menu2Title!, menu2DefaultValue!, menu2Options,
                            (value) {
                            setState(() {
                              menu2DefaultValue = value;
                            });
                          })
                        : Container(),
                    menu3Options.isNotEmpty
                        ? getDropMenu(
                            menu3Title!, menu3DefaultValue!, menu3Options,
                            (value) {
                            setState(() {
                              menu3DefaultValue = value;
                            });
                          })
                        : Container(),
                    isNeedTextField
                        ? Container(
                            alignment: Alignment.centerLeft,
                            padding: const EdgeInsets.only(
                                left: 16, top: 16, bottom: 8),
                            child: const Text(
                              "提示词",
                              style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 15,
                                  fontWeight: FontWeight.w600),
                            ),
                          )
                        : Container(),
                    isNeedTextField
                        ? Container(
                            alignment: Alignment.center,
                            margin: const EdgeInsets.fromLTRB(16, 0, 16, 0),
                            height: MediaQuery.of(context).size.height / 5,
                            width: MediaQuery.of(context).size.width - 32,
                            decoration: BoxDecoration(
                              // color: ChatColors.commonLightColor,
                              color: ChatColors.commonLightColor,
                              borderRadius:
                                  const BorderRadius.all(Radius.circular(12.0)),
                            ),
                            child: Stack(
                              alignment: Alignment.topCenter,
                              children: [
                                Container(
                                  padding:const EdgeInsets.all(8),
                                  height:MediaQuery.of(context).size.height / 5,
                                  child: TextField(
                                    controller: _textEditingController,
                                    style: const TextStyle(color: Colors.white),
                                    keyboardType: TextInputType.text,
                                    keyboardAppearance: Brightness.dark,
                                    focusNode: focusNode,
                                    maxLines: 6,
                                    onChanged: (result) {
                                      setState(() {
                                        //更新发送按钮颜色
                                      });
                                    },
                                    onSubmitted: (text) {
                                      startCreate();
                                    },
                                    textInputAction: TextInputAction.done,
                                    // textAlignVertical: TextAlignVertical.center,
                                    decoration: InputDecoration(
                                        contentPadding:
                                            const EdgeInsets.fromLTRB(8, 0, 8, 8),
                                        border: InputBorder.none,
                                        hintText: creator.example == ""
                                            ? "请详细描述你的要求，越详细，生成的内容越准确。"
                                            : creator.example,
                                        hintStyle:
                                            const TextStyle(color: Colors.grey)),
                                  ),
                                ),

                                Positioned(
                                  left: 2,
                                  bottom: 2,
                                  child: InkWell(
                                    highlightColor: Colors.transparent, // 透明色
                                    splashColor: Colors.transparent, //
                                    onTap: (){
                                      showModalBottomSheet(
                                        context: context,
                                        isDismissible: false,
                                        isScrollControlled: true,
                                        backgroundColor: ChatColors.commonDarkColor,
                                        builder: (context) {
                                          return ProviderDemoApp(
                                            speech: widget.speech,
                                            speechProvider: widget.speechProvider,
                                            speechToTextCallBack: (String value) {
                                              _textEditingController.text = value;
                                              startCreate();
                                            },
                                          );
                                        },
                                      );
                                    },
                                    child: Container(
                                        width: 82,
                                        height: 28,
                                        decoration: BoxDecoration(
                                          color: Colors.black.withOpacity(0.2),
                                          borderRadius:
                                          const BorderRadius.all(Radius.circular(14.0)),
                                        ),
                                        child:  Row(
                                          mainAxisAlignment: MainAxisAlignment.center,
                                          children: [
                                            Icon(
                                              Icons.settings_voice,
                                              color: ChatColors.primaryColor,
                                              size: 12,
                                            ),
                                             Text("语音输入",style: TextStyle(color: Colors.white.withOpacity(0.6),fontSize: 13,fontWeight: FontWeight.w600),)
                                          ],
                                        )),
                                  ),
                                ),
                                Positioned(
                                  right: 6,
                                  bottom: 3,
                                  // 语音跟读
                                  child: InkWell(
                                      onTap: () {
                                        if (_textEditingController
                                            .text.isEmpty) {
                                          paste();
                                        } else {
                                          _textEditingController.text = "";
                                        }
                                        setState(() {});
                                      },
                                      highlightColor: Colors.transparent, // 透明色
                                      splashColor: Colors.transparent, //
                                      child: Text(
                                        _textEditingController.text.isEmpty
                                            ? "粘贴"
                                            : "清空",
                                        style:  TextStyle(
                                            color: ChatColors.primaryColor.withOpacity(0.8),
                                            fontSize: 12,
                                            fontWeight: FontWeight.w600),
                                      )),
                                ),
                              ],
                            ),
                          )
                        : Container(),

                    result == ""
                        ? Container()
                        : Padding(
                            padding: const EdgeInsets.only(
                                left: 16, top: 36, right: 16),
                            child: Row(
                              children: [
                                const Text(
                                  "创作结果:",
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 14,
                                      fontWeight: FontWeight.w700),
                                ),
                                Expanded(child: Container()),
                                InkWell(
                                    onTap: () {
                                      Clipboard.setData(
                                          ClipboardData(text: result));
                                      Utils.showToast("复制成功");
                                    },
                                    highlightColor: Colors.transparent, // 透明色
                                    splashColor: Colors.transparent, //
                                    child: Text(
                                      "复制",
                                      style: TextStyle(
                                          color: ChatColors.primaryColor,
                                          fontSize: 14,
                                          fontWeight: FontWeight.w700),
                                    )),
                              ],
                            ),
                          ),
                    result == ""
                        ? Container()
                        : Container(
                            alignment: Alignment.topLeft,
                            padding: const EdgeInsets.all(8),
                            margin: EdgeInsets.fromLTRB(12, 16, 12,
                                88 + MediaQuery.of(context).padding.bottom),
                            constraints: const BoxConstraints(minHeight: 100),
                            width: MediaQuery.of(context).size.width - 32,
                            decoration: BoxDecoration(
                              border: Border.all(
                                  color: ChatColors.commonLightColor
                                      .withOpacity(0.9),
                                  width: 1),
                              borderRadius:
                                  const BorderRadius.all(Radius.circular(4.0)),
                            ),
                            child: Text(
                              result,
                              style: const TextStyle(
                                  color: Colors.white,
                                  fontSize: 15,
                                  fontWeight: FontWeight.w700),
                            ))
                  ],
                ),
              ),
              Column(
                children: [
                  Expanded(child: Container()),
                  InkWell(
                    highlightColor: Colors.transparent, // 透明色
                    splashColor: Colors.transparent, //
                    onTap: () {
                      startCreate();
                    },
                    child: Container(
                        alignment: Alignment.center,
                        width: MediaQuery.of(context).size.width - 72,
                        height: 42,
                        margin: EdgeInsets.only(
                            bottom: 24 + MediaQuery.of(context).padding.bottom),
                        decoration: BoxDecoration(
                          color: isCreating
                              ? ChatColors.commonLightColor
                              : ChatColors.primaryColor,
                          borderRadius:
                              const BorderRadius.all(Radius.circular(8.0)),
                        ),
                        child: Row(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            isCreating
                                ? const Padding(
                                    padding: EdgeInsets.only(right: 8.0),
                                    child: CupertinoActivityIndicator(
                                        radius: 10.0,
                                        color: Colors.white),
                                  )
                                : Container(),
                            Text(
                              isCreating ? "停止创作" : "开始创作",
                              style: const TextStyle(
                                  color: Colors.white,
                                  fontSize: 15,
                                  fontWeight: FontWeight.w600),
                            ),
                          ],
                        )),
                  ),
                ],
              )
            ],
          )),
    );
  }

  startSSE(String prompt) async {
    if (mounted) {
      setState(() {
        isCreating = true;
      });
    }
    focusNode.unfocus();
    debugPrint("startSSE");
    int msgIndex = 0;

    try {
      Response response = await DioManager.instance.dio
          .get("chatgpt/chat/sseCreator?prompt=$prompt&rolePrompt=${creator.role}");
      var lineRegex = RegExp(r'^([^:]*)(?::)?(?: )?(.*)?$');
      var currentSSEModel = SSEModel(data: '', id: '', event: '');
      // ignore: close_sinks
      streamController = StreamController();

      response.data?.stream
          .transform(unit8Transformer)
          .transform(const Utf8Decoder())
          .transform(const LineSplitter())
          .listen(
        (dataLine) {
          if (dataLine.isEmpty) {
            ///This means that the complete event set has been read.
            ///We then add the event to the stream
            streamController?.add(currentSSEModel);
            currentSSEModel = SSEModel(data: '', id: '', event: '');
            return;
          }

          ///Get the match of each line through the regex
          Match match = lineRegex.firstMatch(dataLine)!;
          var field = match.group(1);
          if (field!.isEmpty) {
            debugPrint("换行？");
            return;
          }
          var value = '';
          if (field == 'data') {
            //If the field is data, we get the data through the substring
            value = dataLine.substring(
              5,
            );
          } else {
            value = match.group(2) ?? '';
          }
          switch (field) {
            case 'event':
              currentSSEModel.event = value;
              break;
            case 'data':
              currentSSEModel.data = (currentSSEModel.data ?? '') + value;

              break;
            case 'id':
              currentSSEModel.id = value;
              break;
            case 'retry':
              break;
          }
        },
        onError: (e, s) {
          debugPrint('---ERROR---');
          debugPrint(e);
          if (mounted) {
            setState(() {
              isCreating = false;
            });
          }
          streamController?.addError(e, s);
        },
        onDone: () {

            if (result.contains(Utils.wxb)) {
              result = Utils.wxb;
            }

          _textEditingController.text = "";
          if (mounted) {
            setState(() {
              isCreating = false;
            });
          }

          debugPrint('Done!');
          scrollBottom();
          if (result.contains(Utils.haveNoTryCount)) {
            Future.delayed(const Duration(milliseconds: 1500), () {
              Navigator.push(context,
                  CupertinoPageRoute(builder: (BuildContext context) {
                return VipPage("创作-$prompt");
              }));
            });
          }
        },
      );

      streamController?.stream.listen((event) {
        setState(() {
          String? msg = event.data;
          if (msg != null) {
            if (msg.isEmpty) {
              if (result != "" && !(result.endsWith("\n"))) {
                msg = "\n";
              }
            }
            if (result == "") {
              result = msg;
            } else {
              result = "$result$msg";
              msgIndex += 1;
            }

            if (msgIndex % 20 == 0) {
              scrollBottom();
            }
          }
        });
      });
    } catch (e) {
      debugPrint('Error making request: $e');
    }
  }

  startCreate() {
    if (isCreating) {
      stopCreator();
      isCreating = false;
    } else {
      if (_textEditingController.text != "" || !isNeedTextField) {
        // _textEditingController.text = "";
        result = "";
        prompt = creator.prompt;
        if (menuDefaultValue != null) {
          prompt = prompt.replaceAll("{1}", menuDefaultValue!);
        }

        if (menu2DefaultValue != null) {
          prompt = prompt.replaceAll("{2}", menu2DefaultValue!);
        }

        if (menu3DefaultValue != null) {
          prompt = prompt.replaceAll("{3}", menu3DefaultValue!);
        }

        if (prompt.contains("{0}")){
          prompt = prompt.replaceAll("{0}", _textEditingController.text);
        }
        startSSE(prompt);
      } else {
        Utils.showToast("请填写提示词");
      }
    }
    if (mounted) {
      setState(() {});
    }
  }

  void scrollBottom() {
    _controller.animateTo(
      _controller.position.maxScrollExtent,
      duration: const Duration(milliseconds: 500),
      curve: Curves.linear,
    );
  }

  stopCreator() {
    isCreating = true;
    streamController?.close();
    setState(() {});
  }

  /// 获取内容
  paste() async {
    var clipboardData = await Clipboard.getData(Clipboard.kTextPlain);
    if (mounted) {
      setState(() {
        _textEditingController.text = clipboardData?.text ?? '';
      });
    }
  }

  getDropMenu(String title, String dropdownValue, List<String> items,
      DropMenuCallBack callBack) {
    debugPrint(
        "title=$title,dropdownValue=$dropdownValue,size=${items.length}");
    return Container(
      width: MediaQuery.of(context).size.width - 32,
      height: 42,
      padding: const EdgeInsets.only(left: 12, right: 12),
      margin: const EdgeInsets.only(top: 12),
      decoration: BoxDecoration(
        border: Border.all(
            color: ChatColors.commonLightColor, width: 1),
        borderRadius: const BorderRadius.all(Radius.circular(12.0)),
      ),
      child: Row(
        children: [
          Text(
            title,
            style: const TextStyle(
                color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500),
          ),
          Expanded(child: Container()),
          DropdownButton<String>(
            underline: Container(),
            dropdownColor: ChatColors.commonLightColor,
            style: const TextStyle(
                color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500),
            value: dropdownValue,
            onChanged: (String? newValue) {
              if (newValue != null) {
                callBack(newValue);
              }
            },
            items: items.map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Text(value),
              );
            }).toList(),
          ),
        ],
      ),
    );
  }
}

typedef DropMenuCallBack = void Function(String? value);
